package com.quectel.cms.service.sys;

import cn.hutool.extra.servlet.ServletUtil;
import com.quectel.cms.interceptor.LoginUserSession;
import com.quectel.constant.global.SystemConstants;
import com.quectel.sys.module.sys.dto.*;
import com.quectel.sys.module.sys.dto.mongo.SysLogDto;
import com.quectel.sys.module.sys.service.*;
import com.quectel.util.common.Response;
import com.quectel.util.http.RequestUtils;
import com.quectel.util.security.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 登录所用到的公共代码
 *
 * @author caolu
 * @email louis.cao@quectel.com
 */
@Slf4j
@Service
public class ApiSysLoginService {

    @DubboReference
    private SysUserService sysUserService;
    @DubboReference
    private SysRoleService sysRoleService;
    @DubboReference
    private SysGroupService sysGroupService;
    @DubboReference
    private SysTenantService sysTenantService;
    @DubboReference
    private SysLogService sysLogService;

    /**
     * 根据查询到的用户得到用户的session
     *
     * @param sysUserDto
     * @return response.success后返回响应的session
     */
    public Response<LoginUserSession> buildSessionBySysUser(SysUserDto sysUserDto) {

        if (sysUserDto == null) {
            return Response.error("用户不存在");
        }
        if (Objects.equals(sysUserDto.getStatus(), SystemConstants.ABNORMAL)) {
            return Response.error("账号禁用");
        }
        SysGroupDto sysGroupDto = sysGroupService.selectById(sysUserDto.getGroupId());
        if (Objects.equals(sysGroupDto.getStatus(), SystemConstants.ABNORMAL)) {
            return Response.error("组被禁用");
        }
        SysTenantDto sysTenantDto = sysTenantService.selectById(sysUserDto.getTenantId());
        if (Objects.equals(sysTenantDto.getStatus(), SystemConstants.ABNORMAL)) {
            return Response.error("租户被禁用");
        }

        Set<String> userRoles = new HashSet<>();
        Set<String> userPermissions = new HashSet<>();

        List<SysRoleDto> userRoleList = sysUserService.selectById(sysUserDto.getId()).getUserRoleList();
        for (SysRoleDto sysRoleDto : userRoleList) {
            if (StringUtils.isNotBlank(sysRoleDto.getName())) {
                userRoles.add(sysRoleDto.getName());
            }
            List<SysMenuDto> userMenuList = sysRoleService.selectById(sysRoleDto.getId()).getRoleMenuList();
            for (SysMenuDto sysMenuDto : userMenuList) {
                if (sysMenuDto.isChecked() && StringUtils.isNotBlank(sysMenuDto.getPermission())) {
                    userPermissions.add(sysMenuDto.getPermission());
                }
            }
        }
        String token = TokenUtils.genRandomToken();

        LoginUserSession session = new LoginUserSession();
        session.setToken(token);
        session.setUserId(sysUserDto.getId());
        session.setUsername(sysUserDto.getUsername());
        session.setAccount(sysUserDto.getAccount());
        session.setUserRoles(userRoles);
        session.setPermissions(userPermissions);

        session.setGroupId(sysGroupDto.getId());
        session.setGroupCode(sysGroupDto.getCode());
        session.setGroupName(sysGroupDto.getName());

        session.setTenantId(sysTenantDto.getId());
        session.setTenantCode(sysTenantDto.getCode());
        session.setLogo(sysTenantDto.getLogo());
        session.setLogoBig(sysTenantDto.getLogoBig());
        session.setScreenUrl(sysTenantDto.getScreenUrl());

        session.setIsPartyManager(sysGroupDto.getIsPartyManager());
        session.setPartyId(sysGroupDto.getPartyId());

        return Response.<LoginUserSession>ok().wrap(session);
    }


    public void saveLoginLog(long loginStartTime, LoginUserSession session) {

        try {
            SysLogDto sysLogDto = new SysLogDto();
            if (session != null) {
                sysLogDto.setTenantId(session.getTenantId());
                sysLogDto.setAccount(session.getAccount());
                sysLogDto.setUsername(session.getUsername());
                sysLogDto.setGroupName(session.getGroupCode());
            }
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            sysLogDto.setRequesterIp(RequestUtils.getRealIp(request));
            sysLogDto.setRequestUri("/sys/login");
            sysLogDto.setMethodString("Response com.quectel.cms.controller.sys.SysLoginController.login(SysUserDto)");
            sysLogDto.setExecuteDuration(System.currentTimeMillis() - loginStartTime);
            sysLogDto.setLog("登录成功");

            sysLogDto.setCreateTime(new Date());
            sysLogService.save(sysLogDto);
        } catch (Exception e) {
            log.error("存入操作日志出错", e);
        }

    }
}
